#!/usr/bin/python
#
# File to manage Windows session information.
#
# There seems no simple way of determining what application are running or what
# their current state is. Hence need specific code for each application.
#
import datetime
import os.path
import sys
import time

def get_system_state():
    """Returns the system state to allow the session to be captured."""
    # Currently just a place holder
    return set()

def start_system_monitor():
    """Returns the system state to allow the session to be captured."""
    # Currently just a place holder
    return set()

def get_applications(known_apps=[]):
    return set()

def get_application(name):
    """Return an app or custom app depending on the executable name."""
    exe = os.path.basename(name).lower()
    if exe in custom_apps:
        detail = custom_apps[exe]
        return detail[1](detail[0], *detail[2:])
    else:
        return Application(name)

def get_application_from_xml(name):
    """Return an application from the given xml."""
    app_type = None 
    for child_node in node.childNodes:
        if child_node.tagName == 'type':
            app_type = child_node.firstChild.nodeValue
        if child_node.tagName == 'name':
            name = child_node.firstChild.nodeValue

    if app_type in app_types:
        application = app_types[app_type].from_xml(node)
    else:
        application = Application(name)

def get_processes():
    """Return a list of processes."""
    processes = {}
    for process_id in win32process.EnumProcesses():
        try:
            process = win32api.OpenProcess(win32security.POLICY_ALL_ACCESS, False, process_id)
            modules = win32process.EnumProcessModules(process)
            path = win32process.GetModuleFileNameEx(process, modules[0])
            processes[process_id] = get_application(path)
            owner = win32security.GetUserObjectSecurity(process, win32security.OWNER_SECURITY_INFORMATION).GetSecurityDescriptorOwner()
        except pywintypes.error:
           # Ignore access denied errors while attempting to connect to processes we may not own
           pass
           #print 'failed to open %d (Exception: %s)' % (process_id, str(sys.exc_info()))
    return processes

def get_files():
    """Return a list of the visited files."""
    return set()

_FILETIME_null_date = datetime.datetime(1601, 1, 1, 0, 0, 0)
def FiletimeToDateTime(ft):
    timestamp = ft.dwHighDateTime
    timestamp <<= 32
    timestamp |= ft.dwLowDateTime
    return _FILETIME_null_date + datetime.timedelta(seconds=-time.timezone, microseconds=timestamp / 10)

class Visited_Url:
    """Manage URLs."""

    def __init__(self, title, url, time):
        """Store the data for the URL."""
        self.__title = title
        self.__url = url
        self.__time = time

    def __str__(self):
        """Returns a string representation of the item."""
        url = self.__url.encode('utf-8') if self.__url else None
        if self.__title:
            title = self.__title.encode('utf-8')
        else:
            title = os.path.basename(url)
        return '%s: %s, %s' % (self.__time.strftime("%c"), title, url)

    def get_children(self):
        """Return list of child items."""
        # Required for interface to list view
        return []

    def get_time(self):
        """Return the time this URL was visited."""
        return self.__time
    
    time = property(get_time)

    def visit(self):
        """Revisit the URL using default operation."""
        win32api.ShellExecute(0, None, self.__url, None, os.getcwd(), 0)

def get_links(starting_time=None):
    """Return the list of visited URLs."""
    result = []
    history = CreateObject(urlhistLib.UrlHistory)
    for item in history.EnumUrls():
        time = FiletimeToDateTime(item.ftLastVisited)
        if not starting_time or time > starting_time:
            result.append(Visited_Url(item.pwcsTitle, item.pwcsUrl, time))
    return result

def process_window(window, data):
    """Process windows returned by EnumWindows."""
    if win32gui.IsWindowVisible(window):
        print "%s : %s" % (win32gui.GetClassName(window), win32gui.GetWindowText(window))

    return True

# Module test code
if __name__ == "__main__":
    import operator
    history = get_links(datetime.datetime.now() - datetime.timedelta(1))
    history.sort(key=operator.attrgetter('time'))
    print '\n'.join([str(item) for item in history])
